package org.zebra.trans.core.handler;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.extern.slf4j.Slf4j;
import org.zebra.trans.Trans;
import org.zebra.trans.core.Translation;

import java.io.IOException;
import java.util.Map;
import java.util.Objects;

/**
 * 翻译处理器
 *
 * @author zhanghongbin
 */
@Slf4j
public class TranslationHandler extends JsonSerializer<Object> implements ContextualSerializer {

    private Trans trans;

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        Translation<?> trans = SpringUtil.getBean(this.trans.translationClass());
        if (ObjectUtil.isNotNull(trans)) {
            // 如果映射字段不为空 则取映射字段的值
            //            value = ReflectPlusUtil.invokeGetter(
            //                    gen.getCurrentValue(), gen.getOutputContext().getCurrentName());
            // 如果为 null 直接写出
            if (ObjectUtil.isNull(value)) {
                gen.writeNull();
                return;
            }
            try {
                Object result = trans.translation(
                        gen.getOutputContext().getCurrentName(), this.trans.readConverterExp(), value);
                String filedName = this.trans.alias();
                if (filedName.isEmpty()) {
                    gen.writeObject(result);
                } else {
                    gen.writeObject(value);
                    // 新增字段
                    if (this.trans.isFlat() && result instanceof Map) {
                        Map mapResult = (Map) result;
                        mapResult.forEach((k, v) -> {
                            try {
                                gen.writeFieldName(k.toString());
                                gen.writeObject(v);
                            } catch (Exception e) {
                            }
                        });
                    } else {
                        gen.writeFieldName(this.trans.alias());
                        gen.writeObject(result);
                    }
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        } else {
            gen.writeObject(value);
        }
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property)
            throws JsonMappingException {
        Trans trans = property.getAnnotation(Trans.class);
        if (Objects.nonNull(trans)) {
            this.trans = trans;
            return this;
        }
        return prov.findValueSerializer(property.getType(), property);
    }
}
